<template>
	<view class="ljs-tree">
		<view class="ljs-tree-select-myInput" v-if="!multiple">
			<view @click="ljs_tree1Open" class="ljs-tree-select-myInput-input" disabled :style="{
				'padding-right': clearable ? '50upx' : '20upx',
			}">
				<text v-if="ljs_tree1.departmentName !== ''">{{ljs_tree1.departmentName}}</text>
				<text v-else :style="{
					color: placeholderColor
				}">点击选择</text>
				<image
					v-if="clearable && ljs_tree1.departmentName !== ''"
					@click.stop="cleaner"
					class="ljs-tree-select-myInput-input-close"
					:src="require('./images/ico_close.png')"></image>
			</view>
		</view>
		<view class="ljs-tree-select-myInput2" v-if="multiple">
			<view class="ljs-tree-select-myInput2-input" @click="ljs_tree2Open">
				<template v-if="ljs_tree2.chooseDatas.length > 0 && !departmentTag">
					<view class="ljs-tree-select-myInput2-one" v-for="(item, i) in ljs_tree2.chooseDatas" :key="i">
						<text class="ljs-tree-select-chooseName" v-for="(obj, j) in item" :key="j">
							<text>{{obj[useProps.label]}}{{j !== item.length - 1?'-':''}}</text>
						</text>
						<image @click.stop="multipleDelItem(item, i)" class="ljs-tree-select-icoClose" :src="require('./images/ico_close.png')"></image>
					</view>
				</template>
				<template v-else>
					<text :style="{
						color: placeholderColor
					}">点击选择</text>
				</template>
			</view>
		</view>
		<view class="ljs-tree-select" v-show="departmentTag" :style="{
			'z-index': zIndex,
		}">
			<view class="ljs-tree-select-box">
				<view class="ljs-tree-select-title">
					<text>{{title}}</text>
					<view class="ljs-tree-select-closeBut" @click="close">
						<image class="ljs-tree-select-ico" :src="require('./images/ico_close.png')"></image>
					</view>
				</view>
				<view class="ljs-tree-select-con">
					<input v-if="keywordsFilter" @input="KeywordFilter" v-model="search.key" class="ljs-tree-select-search" placeholder="输入关键字进行搜索"/>
					<view class="ljs-tree-select-mainBox">
						<treeSelectOne
							:props="useProps"
							@getChooseValue="getValue"
							@openTagChange="openTagChange"
							:checkStrictly="checkStrictly"
							:multiple="multiple"
							:data="listData"
							:allData="listData"
							:chooseMode="chooseMode"
							:lineModeColor="lineModeColor"
							:icoModeImage="icoModeImage"
							:showAllLevels="showAllLevels"
							:allRow="allRow"
							:showRowNum="showRowNum"
							:lazy="lazy"
							:load="load"
							@lazyChange="lazyChange"></treeSelectOne>
					</view>
				</view>
				<view class="ljs-tree-select-but">
					<button @click="save" class="ljs-tree-select-botton yes">{{submitText}}</button>
					<button @click="close" class="ljs-tree-select-botton no">{{cancelText}}</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import treeSelectOne from "./treeSelectOne.vue";
	import {
		getTreeParents,
		treeFilter
	} from "./base.js";

	export default {
		data() {
			return {
				useProps: {},
				departmentTag: false,
				ljs_tree1: {
					departmentName: '',
				},
				ljs_tree2: {
					chooseDatas: [], // 数据集
				},

				chooseIds: [],
				chooseIdsMultipleBackups: [],
				chooseItems: [],
				listData: [],
				listDataBackups: [],
				listDataMultipleBackups: [],

				search: {
					timer: null,
					key: ''
				}
			}
		},
		props: {
			// 树（Tree）解构数据。
			value: Array,
			// 树（Tree），需要回显的数据，id的数组。注意multiple值需与回显值匹配。
			ids: {
				type: Array,
				default: function() {
					return [];
				}
			},
      // 是否禁用
      disabled:{
        type: Boolean,
        default: false
      },
			// 是否严格的遵守父子节点不互相关联（true: 每一级都能选，false: 只能选最后一级）
			checkStrictly: {
				type: Boolean,
				default: false
			},
			// 是否多选
			multiple: {
				type: Boolean,
				default: false
			},
			// 是否返回完整路径数据集
			showAllLevels: {
				type: Boolean,
				default: true
			},
			// 是否开启筛选模式
			keywordsFilter: {
				type: Boolean,
				default: false
			},
			// 是否可以清空选项
			clearable: {
				type: Boolean,
				default: false
			},
			// 是否显示所有
			allRow: {
				type: Boolean,
				default: true
			},
			// allRow为false时显示几行。
			showRowNum: {
				type: Number,
				default: 1
			},
			// 选择器placeholder颜色
			placeholderColor: {
				type: String,
				default: '#CCC'
			},
			// 弹出层z-index值
			zIndex: {
				type: [String, Number],
				default: 100,
			},
			// 选择器标题
			title: {
				type: String,
				default: '树型选择器'
			},
			// 确定按钮文字
			submitText: {
				type: String,
				default: '确定'
			},
			// 取消按钮文字
			cancelText: {
				type: String,
				default: '取消'
			},
			// 选择模式，默认line，勾选模式ico
			chooseMode: {
				type: String,
				default: 'line'
			},
			// chooseMode选择模式为line时，使用的颜色
			lineModeColor: {
				type: String,
				default: '#5c70fe'
			},
			// chooseMode选择模式为ico时，使用的图片
			icoModeImage: {
				type: String,
				default: require('./images/ico_choose.png')
			},
			// 配置选项，具体见下表
			props: {
				type: Object,
				default: function() {
					return {};
				}
			},
			// 是否懒加载子节点，需与 load 方法结合使用。
			lazy: {
				type: Boolean,
				default: false
			},
			// load 方法。keywordsFilter开启筛选模式，进行快捷搜索后，load方法执行会重新记录数据。
			load: {
				type: Function,
				default: () => {
					return () => {}
				}
			},
		},
		components: {
			treeSelectOne,
		},
		watch: {
			value: {
				handler(n) {
					if (this.listData.length === 0) {
						this.init();
					}
				},
				deep: true
			},
			ids: {
				handler(n) {
					this.showChooseResult();
				},
				deep: true
			},
		},
		mounted() {
			this.init();
		},
		methods: {
			// 关闭
			KeywordFilter() {
				if (this.search.timer !== null) {
					clearTimeout(this.search.timer);
				}
				this.search.timer = setTimeout(() => {
					this.getKeyword();
				}, 300);
			},
			getKeyword() {
				this.listData = JSON.parse(JSON.stringify(this.listDataBackups));
				if (this.search.key !== undefined && this.search.key !== null && this.search.key !== '') {
					this.listData = treeFilter(this.useProps, this.listData, this.search.key);
				}
				this.showChooseResult();
			},

			// 关闭
			close() {
				this.departmentTag = false;
				this.search.key = '';
				// 多选
				if (this.multiple) {
					this.listData = JSON.parse(JSON.stringify(this.listDataMultipleBackups));
				} else {
					this.listData = JSON.parse(JSON.stringify(this.listDataBackups));
				}
				this.showChooseResult('close');
				this.$emit('close');
			},
			// 单选 - 打开
			ljs_tree1Open() {
        if(this.disabled) return
				this.departmentTag = true;
				this.getKeyword();
			},
			// 多选 - 打开
			ljs_tree2Open() {
        if(this.disabled) return
				if (!this.showAllLevels) {
					const tempIds = [];
          let ids= this.ids
          //判断ids是不是数组
          if (Array.isArray(ids)) {

          } else {
            ids=[]
          }
          ids.forEach((item) => {
						item.splice(0, item.length - 1);
					});
				}
				this.departmentTag = true;
				this.getKeyword();
				this.listDataMultipleBackups = JSON.parse(JSON.stringify(this.listData));
				this.chooseIdsMultipleBackups = JSON.parse(JSON.stringify(this.ids));
			},

			// 清除按钮
			cleaner() {
				this.$emit("getChooseValue", [], null); // 继续向上传递
			},

			// 多选开启时：单项的删除按钮
			multipleDelItem(item, i) {
				this.getValue(this.ids[i], true);
				this.showChooseResult();
				// 多选选
				if (this.multiple) {
					this.chooseIds.forEach((item, i) => {
						this.chooseItems.push([]);
						const chooseItems = getTreeParents(this.listData, item[item.length - 1], this.useProps.id, [], this.useProps.children);
						if (this.showAllLevels) {
							this.chooseItems[i].push(chooseItems);
						} else {
							this.chooseItems[i].push(chooseItems[chooseItems.length - 1]);
						}
					});
					this.$emit("getChooseValue", this.chooseIds, this.chooseItems); // 继续向上传递
				}
			},
			// 回显展示效果
			showChooseResult(operate) {
				if (operate === 'close' && this.multiple) {
					this.chooseIds = JSON.parse(JSON.stringify(this.chooseIdsMultipleBackups));
					this.$emit("getChooseValue", this.chooseIds, null); // 继续向上传递
				} else {
					this.chooseIds = this.ids;
				}
				this.chooseItems = [];
				// 处理展示数据
				// 单选
				if (!this.multiple) {
					this.changeValue(this.listData, JSON.parse(JSON.stringify(this.chooseIds)));
					this.openTagDg2(this.listData, this.chooseIds[this.chooseIds.length - 1], true);
				} else {
					this.chooseIds.forEach((item) => {
						this.changeValue(this.listData, JSON.parse(JSON.stringify(item)));
						this.openTagDg2(this.listData, item[item.length - 1], true);
					});
				}

				// 处理输入框显示问题
				if (this.chooseIds.length !== 0 && this.listData.length > 0) {
					// 单选
					if (!this.multiple) {
						const parents = getTreeParents(this.listData, this.ids[this.ids.length - 1], this.useProps.id, [], this.useProps.children);
						// 是否完整路径
						if (this.showAllLevels) {
							this.ljs_tree1.departmentName = "";
							parents.forEach((item, i)=>{
								this.ljs_tree1.departmentName += item[this.useProps.label] + "-";
							});
							this.ljs_tree1.departmentName = this.ljs_tree1.departmentName.substring(0, this.ljs_tree1.departmentName.length - 1);
						} else {
							this.ljs_tree1.departmentName = parents[parents.length - 1][this.useProps.label];
						}
					}
					// 多选
					else {
						const chooseDatas = [];
						this.chooseIds.forEach((item) => {
							const parents = getTreeParents(this.listData, item[item.length - 1], this.useProps.id, [], this.useProps.children);
							// 是否完整路径
							if (this.showAllLevels) {
								chooseDatas.push(parents);
							} else {
								chooseDatas.push([parents[parents.length - 1]]);
							}
						});
						this.ljs_tree2.chooseDatas = chooseDatas;
					}
				} else {
					this.ljs_tree1.departmentName = '';
					this.ljs_tree2.chooseDatas = [];
				}
			},

			// 推完整路径，解决小程序，展开后选中父节点自动收起问题。
			openTagChange(ids, openTag) {
				this.openTagDg(this.listData, ids[ids.length - 1], openTag);
				// this.listDataBackups = JSON.parse(JSON.stringify(this.listData));
			},
			// 递归改值 - 改变当前节点是否展开
			// data：树数据
			// id：展开或收起的对象id
			// openTag：状态值
			openTagDg(data, id, openTag) {
				data.forEach((item, i) => {
					if (item[this.useProps.id] === id) {
						item.openTag = openTag;
					}

					if (item[this.useProps.children] !== undefined) {
						this.openTagDg(item[this.useProps.children], id, openTag);
					}
				});
			},
			// 递归改值 - 改变当前节点及其父节点是否展开
			// data：树数据
			// id：展开或收起的对象id
			// openTag：状态值
			openTagDg2(data, id, openTag) {
				const nums = data.length;
				for (let i = 0; i < nums; i++) {
					const item = data[i];
					if (item[this.useProps.id] === id) {
						return true;
					}

					if (item[this.useProps.children] !== undefined) {
						const tag = this.openTagDg2(item[this.useProps.children], id, openTag);
						if (tag) {
							item.openTag = openTag;
							return tag;
						}
					}
				}
				return false;
			},

			lazyChange(ids, children) {
				this.lazyDg(true, this.listData, ids[ids.length - 1], children);
				this.listDataBackups = JSON.parse(JSON.stringify(this.listData));
			},
			lazyDg(backTag, data, id, children) {
				if (!backTag) {
					return backTag;
				}
				data.forEach((item, i) => {
					if (item[this.useProps.id] === id) {
						item[this.useProps.children] = JSON.parse(JSON.stringify(this.initValue(children)));
						item[this.useProps.lazyTag] = false;
						backTag = false;
					}
					if (!backTag) {
						return backTag;
					}

					if (item[this.useProps.children] !== undefined) {
						backTag = this.lazyDg(backTag, item[this.useProps.children], id, children);
					}
				});
				return backTag;
			},
			// 选中的值
			save() {
				if (this.chooseIds.length > 0) {
					this.chooseItems = [];
					// 单选
					if (!this.multiple) {
						const item = this.chooseIds;
						const chooseItems = getTreeParents(this.listDataBackups, item[item.length - 1], this.useProps.id, [], this.useProps.children);
						if (this.showAllLevels) {
							this.chooseItems = chooseItems;
						} else {
							this.chooseItems.push(chooseItems[chooseItems.length - 1]);
						}
					}
					// 多选
					else {
						this.chooseIds.forEach((item, i) => {
							this.chooseItems.push([]);
							const chooseItems = getTreeParents(this.listDataBackups, item[item.length - 1], this.useProps.id, [], this.useProps.children);
							if (this.showAllLevels) {
								this.chooseItems[i].push(chooseItems);
							} else {
								this.chooseItems[i].push(chooseItems[chooseItems.length - 1]);
							}
						});
					}
					this.$emit("getChooseValue", this.chooseIds, this.chooseItems); // 继续向上传递

					if (!this.multiple) {
						this.ljs_tree1.departmentName = "";
						this.chooseItems.forEach((item, i)=>{
							this.ljs_tree1.departmentName += item[this.useProps.label] + "-";
						});
						this.ljs_tree1.departmentName = this.ljs_tree1.departmentName.substring(0, this.ljs_tree1.departmentName.length - 1);
					} else {
						const chooseDatas = [];
						this.chooseIds.forEach((item) => {
							const parents = getTreeParents(this.listDataBackups, item[item.length - 1], this.useProps.id, [], this.useProps.children);
							// 是否完整路径
							if (this.showAllLevels) {
								chooseDatas.push(parents);
							} else {
								chooseDatas.push([parents[parents.length - 1]]);
							}
						});
						this.ljs_tree2.chooseDatas = chooseDatas;
					}

					this.departmentTag = false;
					this.search.key = '';
				} else {
					uni.showToast({
						title: '您还没有选择任何项目。',
						duration: 2000,
						icon: "none"
					});
				}
			},
			// 获取tree选择的结果
			// ids的数组
			// oldChoose历史选中状态
			getValue(ids, oldChoose) {
				this.chooseItems = [];
				// 单选
				if (!this.multiple) {
					this.chooseIds = ids;
					this.changeValue(this.listData, JSON.parse(JSON.stringify(this.chooseIds)));
				} else {
					// 选中
					if (!oldChoose) {
						this.chooseIds.push(ids);
					} else {
						// 取消选中
						const nums = this.chooseIds.length;
						const tempids = ids.toString();
						let index = -1;
						for (let i = 0; i < nums; i++) {
							const temp = this.chooseIds[i].toString();
							if (temp === tempids) {
								index = i;
								break;
							}
						}
						if (index > -1) {
							this.chooseIds.splice(index, 1);
						}
					}
					// 多选选中需先进行所有选项的重置。
					this.multipleDataInit(this.listData);

					const chooseIds = JSON.parse(JSON.stringify(this.chooseIds));
					if (chooseIds.length === 0) {
						this.chooseItems = [];
					} else {
						chooseIds.forEach((item) => {
							const chooseItem = this.changeValue(this.listData, item, []);
							this.chooseItems.push(chooseItem);
						});
					}
				}
				// 因filter原因需重新把改变后的listData赋值给filter数据
				// this.listDataBackups = JSON.parse(JSON.stringify(this.listData));
			},
			// 多选模式，一个都没选的重置
			multipleDataInit(data) {
				data.forEach((item, i) => {
					item.choose = false;
					if (item[this.useProps.children] !== undefined) {
						this.multipleDataInit(item[this.useProps.children]);
					}
				});
			},
			// 递归改值 - 只负责该值，不负责获取对象集
			// data：树数据
			// chooseIds：选择的树id数据集
			changeValue(data, chooseIds) {
				const nums = data.length;
				for (let i = 0; i < nums; i++) {
					const item = data[i];
					// 单选
					if (!this.multiple) {
						if (chooseIds[chooseIds.length - 1] === item[this.useProps.id]) {
							item.choose = true;
						} else {
							item.choose = false;
						}
					} else {
						if (chooseIds[chooseIds.length - 1] === item[this.useProps.id]) {
							item.choose = true;
						}
					}
					// 小程序选择bug优化。
					if (chooseIds[0] === item[this.useProps.id]) {
						chooseIds.splice(0, 1);
					}

					if (item[this.useProps.children] !== undefined && item[this.useProps.children].length > 0) {
						this.changeValue(item[this.useProps.children], chooseIds);
					}
				}
			},
			// 初始化
			initValue(data) {
				data.forEach((item, i) => {
					item.choose = false;
					item.openTag = false;
					if (item[this.useProps.lazyTag] === undefined || item[this.useProps.lazyTag] === null) {
						item[this.useProps.lazyTag] = true; // 是否可以执行懒加载
					}
					if (item[this.useProps.children] !== undefined) {
						item[this.useProps.children] = this.initValue(item[this.useProps.children]);
					} else {
						item[this.useProps.children] = [];
					}
				});
				return data;
			},
			init() {
				this.useProps = {
					label: 'label', // 指定选项的值为选项对象的某个属性值
					id: 'id', // 指定选项的值为选项对象的某个属性值
					children: 'children', // 指定选项的子选项为选项对象的某个属性值
					lazyTag: 'lazyTag', // 指定选项的值为选项对象的某个属性值。用于懒加载判定是否可以点击加载下级。默认值true为可点击。
				};
				for (let key in this.props) {
					this.useProps[key] = this.props[key];
				}
				if (this.value.length > 0) {
					this.listDataBackups = JSON.parse(JSON.stringify(this.initValue(this.value)));
					this.listData = JSON.parse(JSON.stringify(this.listDataBackups));
					this.showChooseResult();
				}
			},
		}
	}
</script>

<style lang="scss" scoped>
	@import "./ljs-treeChoose.scss"
</style>
